home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / program / pdmake.arc / MAKE.C < prev    next >
C/C++ Source or Header  |  1986-12-16  |  12KB  |  526 lines

  1.     /***************************************************************\
  2.     *                                *
  3.     *  PDMAKE, Atari ST version                    *
  4.     *                                *
  5.     *  Adapted from mod.sources Vol 7 Issue 71, 1986-12-03.        *
  6.     *                                *
  7.     *  This port makes extensive use of the original net.sources    *
  8.     *  port by Jwahar Bammi.                    *
  9.     *                                *
  10.     *      Ton van Overbeek                        *
  11.     *      Email: TPC862@ESTEC.BITNET                *
  12.     *             TPC862%ESTEC.BITNET@WISCVM.WISC.EDU    (ARPA)    *
  13.     *             ...!mcvax!tpc862%estec.bitnet   (UUCP Europe)    *
  14.     *             ...!ucbvax!tpc862%estec.bitnet  (UUCP U.S.A.)    *
  15.     *             71450,3537  (CompuServe)                *
  16.     *                                *
  17.     \***************************************************************/
  18.  
  19. /*
  20.  *    Do the actual making for make
  21.  */
  22.  
  23. #include <stdio.h>
  24.  
  25. #ifdef unix
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <sys/errno.h>
  29. #endif
  30. #ifdef eon
  31. #include <sys/stat.h>
  32. #include <sys/err.h>
  33. #endif
  34. #ifdef os9
  35. #include <time.h>
  36. #include <os9.h>
  37. #include <modes.h>
  38. #include <direct.h>
  39. #include <errno.h>
  40. #endif
  41. #ifdef ATARIST
  42. #include "astat.h"
  43. #endif
  44.  
  45. #include "h.h"
  46.  
  47.  
  48.  
  49. /*
  50.  *    Exec a shell that returns exit status correctly (/bin/esh).
  51.  *    The standard EON shell returns the process number of the last
  52.  *    async command, used by the debugger (ugg).
  53.  *    [exec on eon is like a fork+exec on unix]
  54.  */
  55. int
  56. dosh(string, shell)
  57. char *    string;
  58. char *    shell;
  59. {
  60.     int    number;
  61.  
  62. #ifdef unix
  63.     return system(string);
  64. #endif
  65. #ifdef ATARIST
  66.     return system(string);
  67. #endif
  68. #ifdef eon
  69.     return ((number = execl(shell, shell,"-c", string, 0)) == -1) ?
  70.         -1:    /* couldn't start the shell */
  71.         wait(number);    /* return its exit status */
  72. #endif
  73. #ifdef os9
  74.     int    status, pid;
  75.  
  76.     strcat(string, "\n");
  77.     if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1)
  78.         return -1;        /* Couldn't start a shell */
  79.     do
  80.     {
  81.         if ((pid = wait(&status)) == -1)
  82.             return -1;    /* child already died!?!? */
  83.     } while (pid != number);
  84.  
  85.     return status;
  86. #endif
  87. }
  88.  
  89.  
  90. /*
  91.  *    Do commands to make a target
  92.  */
  93. void
  94. docmds1(np, lp)
  95. struct name *        np;
  96. struct line *        lp;
  97. {
  98.     bool            ssilent;
  99.     bool            signore;
  100.     int            estat;
  101.     register char *        q;
  102.     register char *        p;
  103.     char *            shell;
  104.     register struct cmd *    cp;
  105.  
  106.  
  107.     if (*(shell = getmacro("SHELL")) == '\0')
  108. #ifdef eon
  109.         shell = ":bin/esh";
  110. #endif
  111. #ifdef unix
  112.         shell = "/bin/sh";
  113. #endif
  114. #ifdef os9
  115.         shell = "shell";
  116. #endif
  117.  
  118.     for (cp = lp->l_cmd; cp; cp = cp->c_next)
  119.     {
  120.         strcpy(str1, cp->c_cmd);
  121.         expand(str1);
  122.         q = str1;
  123.         ssilent = silent;
  124.         signore = ignore;
  125.         while ((*q == '@') || (*q == '-'))
  126.         {
  127.             if (*q == '@')       /*  Specific silent  */
  128.                 ssilent = TRUE;
  129.             else           /*  Specific ignore  */
  130.                 signore = TRUE;
  131.             q++;           /*  Not part of the command  */
  132.         }
  133.  
  134.         if (!domake)
  135.             ssilent = 0;
  136.  
  137.         if (!ssilent)
  138.             fputs("    ", stdout);
  139.  
  140.         for (p=q; *p; p++)
  141.         {
  142.             if (*p == '\n' && p[1] != '\0')
  143.             {
  144.                 *p = ' ';
  145.                 if (!ssilent)
  146.                     fputs("\\\n", stdout);
  147.             }
  148.             else if (!ssilent)
  149.                 putchar(*p);
  150.         }
  151.         if (!ssilent)
  152.             putchar('\n');
  153.  
  154.         if (domake)
  155.         {            /*  Get the shell to execute it  */
  156.             if ((estat = dosh(q, shell)) != 0)
  157.             {
  158.                 if (estat == -1)
  159. #ifdef ATARIST
  160.                     fatal("Couldn't execute %s", q);
  161. #else
  162.                     fatal("Couldn't execute %s", shell);
  163. #endif
  164.                 else
  165.                 {
  166.                     printf("%s: Error code %d", myname, estat);
  167.                     if (signore)
  168.                         fputs(" (Ignored)\n", stdout);
  169.                     else
  170.                     {
  171.                         putchar('\n');
  172.                         if (!(np->n_flag & N_PREC))
  173.                             if (unlink(np->n_name) == 0)
  174.                                 printf("%s: '%s' removed.\n", myname,
  175.                                        np->n_name);
  176.                         exit(estat);
  177.                     }
  178.                 }
  179.             }
  180.         }
  181.     }
  182. }
  183.  
  184.  
  185. docmds(np)
  186. struct name *    np;
  187. {
  188.     register struct line *    lp;
  189.  
  190.  
  191.     for (lp = np->n_line; lp; lp = lp->l_next)
  192.         docmds1(np, lp);
  193. }
  194.  
  195.  
  196. #ifdef os9
  197. /*
  198.  *    Some stuffing around to get the modified time of a file
  199.  *    in an os9 file system
  200.  */
  201. getmdate(fd, tbp)
  202. struct sgtbuf *        tbp;
  203. {
  204.     struct registers    regs;
  205.     static struct fildes    fdbuf;
  206.  
  207.  
  208.     regs.rg_a = fd;
  209.     regs.rg_b = SS_FD;
  210.     regs.rg_x = &fdbuf;
  211.     regs.rg_y = sizeof (fdbuf);
  212.  
  213.     if (_os9(I_GETSTT, ®s) == -1)
  214.     {
  215.         errno = regs.rg_b & 0xff;
  216.         return -1;
  217.     }
  218.     if (tbp)
  219.     {
  220.         _strass(tbp, fdbuf.fd_date, sizeof (fdbuf.fd_date));
  221.         tbp->t_second = 0;    /* Files are only acurate to mins */
  222.     }
  223.     return 0;
  224. }
  225.  
  226.  
  227. /*
  228.  *    Kludge routine to return an aproximation of how many
  229.  *    seconds since 1980.  Dates will be in order, but will not
  230.  *    be lineer
  231.  */
  232. time_t
  233. cnvtime(tbp)
  234. struct sgtbuf        *tbp;
  235. {
  236.     long            acc;
  237.  
  238.  
  239.     acc = tbp->t_year - 80;        /* Baseyear is 1980 */
  240.     acc = acc * 12 + tbp->t_month;
  241.     acc = acc * 31 + tbp->t_day;
  242.     acc = acc * 24 + tbp->t_hour;
  243.     acc = acc * 60 + tbp->t_minute;
  244.     acc = acc * 60 + tbp->t_second;
  245.  
  246.     return acc;
  247. }
  248.  
  249.  
  250. /*
  251.  *    Get the current time in the internal format
  252.  */
  253. time(tp)
  254. time_t *        tp;
  255. {
  256.     struct sgtbuf        tbuf;
  257.  
  258.  
  259.     if (getime(&tbuf) < 0)
  260.         return -1;
  261.  
  262.     if (tp)
  263.         *tp = cnvtime(&tbuf);
  264.  
  265.     return 0;
  266. }
  267. #endif
  268.  
  269. #ifdef ATARIST
  270. /*
  271.  *    Get the current time in the internal format
  272.  */
  273. time(tp)
  274. time_t *        tp;
  275. {
  276.     if (tp)
  277.         *tp = Gettime();
  278.  
  279.     return 0;
  280. }
  281. #endif
  282.  
  283. /*
  284.  *    Get the modification time of a file.  If the first
  285.  *    doesn't exist, it's modtime is set to 0.
  286.  */
  287. void
  288. modtime(np)
  289. struct name *    np;
  290. {
  291. #ifdef unix
  292.     struct stat        info;
  293.     int            fd;
  294.  
  295.  
  296.     if (stat(np->n_name, &info) < 0)
  297.     {
  298.         if (errno != ENOENT)
  299.             fatal("Can't open %s; error %d", np->n_name, errno);
  300.  
  301.         np->n_time = 0L;
  302.     }
  303.     else
  304.         np->n_time = info.st_mtime;
  305. #endif
  306. #ifdef eon
  307.     struct stat        info;
  308.     int            fd;
  309.  
  310.  
  311.     if ((fd = open(np->n_name, 0)) < 0)
  312.     {
  313.         if (errno != ER_NOTF)
  314.             fatal("Can't open %s; error %02x", np->n_name, errno);
  315.  
  316.         np->n_time = 0L;
  317.     }
  318.     else if (getstat(fd, &info) < 0)
  319.         fatal("Can't getstat %s; error %02x", np->n_name, errno);
  320.     else
  321.         np->n_time = info.st_mod;
  322.  
  323.     close(fd);
  324. #endif
  325. #ifdef os9
  326.     struct sgtbuf    info;
  327.     int            fd;
  328.  
  329.  
  330.     if ((fd = open(np->n_name, 0)) < 0)
  331.     {
  332.         if (errno != E_PNNF)
  333.             fatal("Can't open %s; error %02x", np->n_name, errno);
  334.  
  335.         np->n_time = 0L;
  336.     }
  337.     else if (getmdate(fd, &info) < 0)
  338.         fatal("Can't getstat %s; error %02x", np->n_name, errno);
  339.     else
  340.         np->n_time = cnvtime(&info);
  341.  
  342.     close(fd);
  343. #endif
  344. #ifdef ATARIST
  345.     struct stat        info;
  346.     extern int        getstat();        /*  in ststuff.c  */
  347.     extern void        FlipWords();        /*  in ststuff.c  */
  348.  
  349.     if (getstat(np->n_name, &info) < 0)
  350.         np->n_time = 0L;
  351.     else
  352.     {
  353.         FlipWords(&info.st_mod);
  354.         np->n_time = info.st_mod;
  355.     }
  356. #endif
  357. }
  358.  
  359.  
  360. /*
  361.  *    Update the mod time of a file to now.
  362.  */
  363. void
  364. touch(np)
  365. struct name *    np;
  366. {
  367.     char    c;
  368.     int        fd;
  369.  
  370.  
  371.     if (!domake || !silent)
  372.         printf("    touch(%s)\n", np->n_name);
  373.  
  374.     if (domake)
  375.     {
  376. #ifdef unix
  377.         long    a[2];
  378.  
  379.         a[0] = a[1] = time(0);
  380.         if (utime(np->n_name, &a[0]) < 0)
  381.